package com.geodroid.action;

import java.util.ArrayList;

import android.graphics.PointF;
import android.graphics.RectF;
import android.util.Log;
import android.view.MotionEvent;

import com.geodroid.euclidian.Drawable;
import com.geodroid.euclidian.EuclidianView;

public class ActionScroll extends Action {
	float x0 ; 
	float y0 ;
	
	
	/*
	 * pinch zoom
	 */
	private float oldDist;
	private float oldScale=1;
	private int mode = DRAG;
	private PointF mid=new PointF(x0,y0);
	private static final int ZOOM = 0;
	private static final int DRAG = 1;
	private static final int REDRAG = 2;
	
	/**
	 * 
	 */
	public ActionScroll() {
		super();
		// TODO Auto-generated constructor stub
	}

	/**
	 * @param isStarted
	 * @param nbClicked
	 * @param draSel
	 */
	public ActionScroll(boolean isStarted, int nbClicked,
			ArrayList<Drawable> draSel) {
		super(isStarted, nbClicked, draSel);
		// TODO Auto-generated constructor stub
	}

	/**
	 * @param nbClicked
	 * @param draSel
	 */
	public ActionScroll(int nbClicked, ArrayList<Drawable> draSel) {
		super(nbClicked, draSel);
		// TODO Auto-generated constructor stub
	}

	/**
	 * @param nbC
	 */
	public ActionScroll(int nbC) {
		super(nbC);
		// TODO Auto-generated constructor stub
	}

	@Override
	public void dealWith(MotionEvent event, EuclidianView view) {
		//we create the drawable ...
		int action = event.getAction();
		float x = event.getX();
		float y = event.getY();
		float width = event.getTouchMajor();
		float height = event.getTouchMinor();
		RectF touchedArea = new RectF(x-width/2,y-height/2,x+width/2,y+height/2) ;
		switch (action & MotionEvent.ACTION_MASK) {
		case MotionEvent.ACTION_POINTER_DOWN:
			// pinch zoom
				oldScale=1 ;
			   oldDist = spacing(event) ;
			   if (oldDist > 10f) {
			      midPoint(mid, event);
			      mode = ZOOM;
			   }
			   break;
			case MotionEvent.ACTION_DOWN:
				processDown(touchedArea,view) ;
				mode = DRAG ;
				break ;
			case MotionEvent.ACTION_MOVE:
				if(mode==DRAG){
					processMove(touchedArea,view) ;
				}else if(mode==REDRAG){
					processDown(touchedArea,view) ;
					mode=DRAG ;
				}else if (mode==ZOOM){
					float newDist = spacing(event);
				      if (newDist > 10f) {
							Log.d("EuclidianView","oldDist="+oldDist) ;
							Log.d("EuclidianView","newDist="+newDist) ;
						    	  float scaleFactor = newDist / oldDist;
						    	  Log.d("EuclidianView","scaleFactor="+scaleFactor) ;
						    	  float scale =  scaleFactor / oldScale;
						    	  Log.d("EuclidianView","scale="+scale) ;
						    	  view.zoom(mid,scale) ; 
						    	  oldScale *= scale ;

				      }
				}
				break;
			case MotionEvent.ACTION_POINTER_UP : 
				mode = REDRAG ;
				break ;
			case MotionEvent.ACTION_UP: 
				mode=DRAG ;
				break ;
			default:
		}
		
		
	}
	
	private float spacing(MotionEvent event) {
		   float x = event.getX(0) - event.getX(1);
		   float y = event.getY(0) - event.getY(1);
		   return (float) Math.sqrt(x * x + y * y);
		}
	private void midPoint(PointF point, MotionEvent event) {
		   float x = event.getX(0) + event.getX(1);
		   float y = event.getY(0) + event.getY(1);
		   point.set(x / 2, y / 2);
		}
	
	@Override
	public void process(RectF touchedArea, EuclidianView view) {
		float u = touchedArea.centerX()-x0 ; 
		float v= touchedArea.centerY()-y0 ; 
		view.scroll(u,v) ;
		x0 = touchedArea.centerX() ;
		y0 = touchedArea.centerY() ; 
	}

	@Override
	public void processDown(RectF touchedArea, EuclidianView view) {
		x0 = touchedArea.centerX() ; 
		y0 = touchedArea.centerY() ; 
	}

	@Override
	public void processMove(RectF touchedArea, EuclidianView view) {
		this.process(touchedArea, view) ; 
	}

	@Override
	public void processUp(RectF touchedArea, EuclidianView view) {

	}

	@Override
	public boolean validate(Drawable d) {
		return true;
	}

}
